//
// Created by dyc on 25-1-6.
//

#include "control.h"

std::atomic<bool> THREAD_ALL_RUN=true;

namespace hitcrt {
    Control::Control() {
        LoadParam params;
        params.getCameraParam(camera);
        YAML::Node config = params.getControlParam();
        //加载基本控制参数
        IF_CAMERA = config["Control"]["IF_CAMERA"].as<int>();
        IF_SHOW_IMG = config["Control"]["IF_SHOW_IMG"].as<int>();
        IF_SHOW_MASK = config["Control"]["IF_SHOW_MASK"].as<int>();
        SAVE_VIDEO = config["Control"]["SAVE_VIDEO"].as<int>();
        SAVE_PATH = config["Control"]["SAVE_PATH"].as<std::string>();
        SAVE_NAME = config["Control"]["SAVE_NAME"].as<std::string>();
        VIDEO_PATH = config["Video"]["VideoPath"].as<std::string>();
        VIDEO_FPS = config["Video"]["Video_FPS"].as<double>();
        IF_DETECT = config["Control"]["IF_DETECT"].as<int>();
        IF_CALCULATE = config["Control"]["IF_CALCULATE"].as<int>();

        //加载小球检测参数
        const auto maxYellow = config["Detect"]["yellow"]["max"].as<std::vector<int>>();
        detector.maxYellow = cv::Scalar(maxYellow[0],maxYellow[1],maxYellow[2]);
        const auto minYellow = config["Detect"]["yellow"]["min"].as<std::vector<int>>();
        detector.minYellow = cv::Scalar(minYellow[0],minYellow[1],minYellow[2]);
        const auto maxBlack = config["Detect"]["black"]["max"].as<std::vector<int>>();
        detector.maxBlack = cv::Scalar(maxBlack[0],maxBlack[1],maxBlack[2]);
        const auto minBlack =config["Detect"]["black"]["min"].as<std::vector<int>>();
        detector.minBlack = cv::Scalar(minBlack[0],minBlack[1],minBlack[2]);
        const auto maxBlue = config["Detect"]["blue"]["max"].as<std::vector<int>>();
        detector.maxBlue = cv::Scalar(maxBlue[0],maxBlue[1],maxBlue[2]);
        const auto minBlue = config["Detect"]["blue"]["min"].as<std::vector<int>>();
        detector.minBlue = cv::Scalar(minBlue[0],minBlue[1],minBlue[2]);
        const auto maxRed_1 = config["Detect"]["red_1"]["max"].as<std::vector<int>>();
        detector.maxRed_1 = cv::Scalar(maxRed_1[0],maxRed_1[1],maxRed_1[2]);
        const auto minRed_1 = config["Detect"]["red_1"]["min"].as<std::vector<int>>();
        detector.minRed_1 = cv::Scalar(minRed_1[0],minRed_1[1],minRed_1[2]);
        const auto maxRed_2 = config["Detect"]["red_2"]["max"].as<std::vector<int>>();
        detector.maxRed_2 = cv::Scalar(maxRed_2[0],maxRed_2[1],maxRed_2[2]);
        const auto minRed_2 = config["Detect"]["red_2"]["min"].as<std::vector<int>>();
        detector.minRed_2 = cv::Scalar(minRed_2[0],minRed_2[1],minRed_2[2]);

        detector.IF_MASK_PROCESS = config["Detect"]["mask_process"].as<int>();
        detector.MASK_PROCESS_ITERATION = config["Detect"]["mask_process_iterations"].as<int>();

        //获取相机内参
        params.getCamFixParam(detector.m_cameraMatrix,detector.m_distCoeffs);

        //检测筛选参数
        detector.m_areaMin = config["Detect"]["areaMin"].as<double>();
        detector.m_areaMax = config["Detect"]["areaMax"].as<double>();

    }

    void Control::run() {
        //摄像头读图
        if (IF_CAMERA) {
            camera.open();
            cv::Mat frame;
            while (THREAD_ALL_RUN) {
                // 读取摄像头图像
                camera.cap >> frame;
                mutex.lock();
                image = frame.clone();
                mutex.unlock();
                if (frame.empty()) {
                    std::cerr << "无法读取帧" << std::endl;
                    break;
                }
                FPS.record();
                if (FPS.count==30) {
                    std::cout << FPS.calculate() << std::endl;
                }
            }
        }
        //视频读图
        else {
            cv::VideoCapture cap(VIDEO_PATH);
            if (!cap.isOpened()) {
                std::cerr << "无法打开视频文件" << std::endl;
                return;
            }
            cv::Mat frame;
            while (THREAD_ALL_RUN) {
                // 读取视频的下一帧
                cap >> frame;
                mutex.lock();
                image = frame.clone();
                mutex.unlock();
                if (frame.empty()) {
                    std::cerr << "无法读取帧" << std::endl;
                    break;
                }
            }
        }


    }

    void Control::show()  {
        if (IF_SHOW_MASK && IF_SHOW_IMG) {
            while (THREAD_ALL_RUN) {
                const int frame_delay = static_cast<int>(1000 / VIDEO_FPS);
                mutex.lock();
                cv::Mat frame = image.clone();
                cv::Mat blueMask = detector.blueMask;
                cv::Mat redMask = detector.redMask;
                cv::Mat yellowMask = detector.yellowMask;
                cv::Mat blackMask = detector.blackMask;
                mutex.unlock();
                if (!frame.empty()) {
                    cv::namedWindow("image", cv::WINDOW_NORMAL);
                    cv::imshow("image",image);
                }
                if (!blueMask.empty()) {
                    cv::namedWindow("blueMask", cv::WINDOW_NORMAL);
                    cv::imshow("blueMask",blueMask);
                }
                if (!redMask.empty()) {
                    cv::namedWindow("redMask", cv::WINDOW_NORMAL);
                    cv::imshow("redMask",redMask);

                }
                if (!yellowMask.empty()) {
                    cv::namedWindow("yellowMask", cv::WINDOW_NORMAL);
                    cv::imshow("yellowMask",yellowMask);
                }
                if (!blackMask.empty()) {
                    cv::namedWindow("blackMask", cv::WINDOW_NORMAL);
                    cv::imshow("blackMask",yellowMask);
                }
                cv::waitKey(frame_delay);
            }
        }
        else if (IF_SHOW_IMG) {
            while (THREAD_ALL_RUN) {
                const int frame_delay = static_cast<int>(1000 / VIDEO_FPS);
                mutex.lock();
                cv::Mat frame = image.clone();
                mutex.unlock();
                if (!frame.empty()) {
                    cv::namedWindow("image", cv::WINDOW_NORMAL);
                    cv::imshow("image",image);
                }
                cv::waitKey(frame_delay);
            }
        }
    }

    void Control::detect() {
        if (IF_DETECT) {
            while (THREAD_ALL_RUN) {
                if (!image.empty()) {
                    detector.detect(image);
                }
            }

        }
    }
}